<!--结构树-->

<template>
  <div class="structure-tree-table">

    <div class="toolbar">
      <Tooltip transfer content="全部锁定" placement="bottom">
        <span class="tool-btn" @click.stop="lockAndUnloadAll(false)"><Icon type="md-lock" size="16"/></span>
      </Tooltip>
      <Tooltip transfer content="全部解锁" placement="bottom">
        <span class="tool-btn" @click.stop="lockAndUnloadAll(true)"><Icon type="md-unlock" size="16"/></span>
      </Tooltip>
      <Tooltip v-if="pageMetadata.develop_canvas == 'AbsoluteLayoutCanvas'" transfer content="全部显示" placement="bottom">
        <span class="tool-btn" @click.stop="showAndHideAll('block')"><Icon type="md-eye" size="16"/></span>
      </Tooltip>
      <Tooltip v-if="pageMetadata.develop_canvas == 'AbsoluteLayoutCanvas'" transfer content="全部隐藏" placement="bottom">
        <span class="tool-btn" @click.stop="showAndHideAll('none')"><Icon type="md-eye-off" size="16"/></span>
      </Tooltip>
    </div>

    <div class="structure-tree-body" @click="structureTreeTableClickHandler()">
      <span class="none-message" v-if="structureTreeData.length == 0">结构树</span>

      <div v-if="pageMetadata.id"
           class="canvas-item"
           :class="{'active': canvasEnabled}"
           @click="locationTargetCanvas">
        <div class="content clearfix">
          <Icon type="md-grid" size="20" :style="{float: 'left'}"/>
          <p class="float-left" style="margin-top: 1px; margin-left: 3px;">画布</p>
        </div>
      </div>

      <div class="tree-item-container"
           v-for="(item, index) in structureTreeData"
           :key="index">

        <StructureTreeGroupItem v-if="item.type == 'groupItem'" :groupItem="item" @itemClick="structureTreeItemClickHandler"></StructureTreeGroupItem>
        <StructureTreeLayoutItem v-if="item.type == 'layoutItem'" :layoutItem="item" @itemClick="structureTreeItemClickHandler"></StructureTreeLayoutItem>
      </div>
    </div>

    <div class="structure-tree-footer">
      <Tooltip v-if="pageMetadata.develop_canvas == 'AbsoluteLayoutCanvas'" content="关闭所有独显图层状态" placement="top-start">
        <span class="tool-btn"
              :class="{'disabled': alongShowTargetIdList.length == 0}"
              @click="toolBtnHandler('closeAllAlongShow')"><Icon custom="iconfont icon-cancel-along-show" size="14"/></span>
      </Tooltip>
      <Tooltip v-if="pageMetadata.develop_canvas == 'AbsoluteLayoutCanvas'" content="组合" placement="top">
        <span class="tool-btn"
              :class="{'disabled': toolBtnDisabled('createGroup')}"
              @click.stop="toolBtnHandler('createGroup')"><Icon custom="iconfont iconreferenceentitydefc" size="14" style="margin-top: 1px;"/></span>
      </Tooltip>
      <Tooltip content="锁定、解锁" placement="top">
        <span class="tool-btn"
              :class="{'disabled': toolBtnDisabled()}"
              @click.stop="toolBtnHandler('reverseLockItems')"><Icon custom="iconfont iconlock" size="14"/></span>
      </Tooltip>
      <Tooltip v-if="pageMetadata.develop_canvas == 'AbsoluteLayoutCanvas'" content="复制" placement="top">
        <span class="tool-btn"
              :class="{'disabled': toolBtnDisabled()}"
              @click.stop="toolBtnHandler('copyItems')" title="复制"><Icon type="md-copy" size="14"/></span>
      </Tooltip>
      <Tooltip content="删除" placement="top">
        <span class="tool-btn"
              :class="{'disabled': toolBtnDisabled()}"
              @click.stop="toolBtnHandler('delItems')"><Icon type="md-trash" size="14"/></span>
      </Tooltip>
    </div>

    <div class="along-comp-edit-model-mask-layer" v-if="isAlongCompEditModel"></div>

  </div>
</template>

<script>
  import _ from 'lodash'

  import StructureTreeLayoutItem from './StructureTreeLayoutItem'
  import StructureTreeGroupItem from './StructureTreeGroupItem'

  import { createHelpers } from 'vuex-map-fields';

  const { mapFields } = createHelpers({
    getterType: 'designer/getField',
    mutationType: 'designer/updateField',
  });

  export default {
    name: 'StructureTreeTable',
    components: {
      StructureTreeLayoutItem,
      StructureTreeGroupItem,
    },
    data() {
      return {
        keydownFlag: false, // 用此变量来限制keydown事件在windows系统下无限触发的问题
      }
    },
    mounted() {
      this.$EventBus.$on('pn_closeStructureTreeRenameModal', () => {
        this.registerKeyDownAndUp();
      })
    },
    destroyed() {
      this.$EventBus.$off('pn_closeStructureTreeRenameModal')
    },
    methods: {

      structureTreeItemClickHandler (params) {
        this.registerKeyDownAndUp();

        if (params.layoutItemId) {
          if(this.$store.getters['designer/getKeepCtrl']) {
            let selectLayoutItemIds = this.currentSelectLayoutItemIds.concat();

            if(selectLayoutItemIds.indexOf(params.layoutItemId) > -1) {
              for (let i=0; i<selectLayoutItemIds.length; i++) {
                if(params.layoutItemId == selectLayoutItemIds[i]) {
                  if(selectLayoutItemIds.length > 1) {
                    selectLayoutItemIds.splice(i, 1);
                    i--
                  }
                }
              }
            }else {
              selectLayoutItemIds.pushNoRepeat(params.layoutItemId);
            }
            this.$store.commit('designer/setCurrentSelectLayoutItemIds', selectLayoutItemIds);
          } else {
            if(this.$store.state.designer.currentSelectLayoutItemIds.indexOf(params.layoutItemId) == -1) {
              this.$store.commit('designer/setCurrentSelectLayoutItemIds', []) // 清除ctrl选中的布局块
            }
          }
        }
        if (params.groupItemId) {
          if(this.$store.getters['designer/getKeepCtrl']) {
            let selectGroupItemIds = this.currentSelectGroupItemIds.concat();

            if(selectGroupItemIds.indexOf(params.groupItemId) > -1) {
              for (let i=0; i<selectGroupItemIds.length; i++) {
                if(params.groupItemId == selectGroupItemIds[i]) {
                  if(selectGroupItemIds.length > 1) {
                    selectGroupItemIds.splice(i, 1);
                    i--
                  }
                }
              }
            }else {
              selectGroupItemIds.pushNoRepeat(params.groupItemId);
            }
            this.$store.commit('designer/setCurrentSelectGroupItemIds', selectGroupItemIds);
          } else {
            if(this.currentSelectGroupItemIds.indexOf(params.groupItemId) == -1) {
              this.$store.commit('designer/setCurrentSelectGroupItemIds', []) // 清除ctrl选中的布局块
            }
          }
        }

      },

      registerKeyDownAndUp () {
        let _this = this;

        $(document).unbind('keydown');
        $(document).unbind('keyup');

        $(document).bind("keydown", function(e) {
          let keyCode = event.keyCode || event.which || event.charCode;
          let ctrlKey = event.ctrlKey || event.metaKey;

          if(ctrlKey && keyCode == 83) {
            e.preventDefault();
            _this.$DesignerCommonUtil.saveCurrentEditPage(_this.pageMetadata)
          }

          // 快捷删除，mac下为cmd+backspace，windows下为delete键
          if ((ctrlKey && keyCode == 8) || keyCode == 46) {
            _this.$DesignerCommonUtil.backspaceDeleteLayoutOrGroupItem(
                _this.currentSelectLayoutItemId, _this.currentSelectLayoutItemIds, _this.currentSelectGroupItemId, _this.currentSelectGroupItemIds)
          }

          // ctrl + z 回退、撤销操作
          if (ctrlKey && keyCode == 90) {
            e.preventDefault();
            _this.$store.dispatch('designer/stepBackward');
          }

          // 解决windows系统下，keydown一直触发的问题
          if (_this.keydownFlag) {
            return
          }
          _this.keydownFlag = true;

          if(_this.$PnUtil.isMac()) {
            if(ctrlKey) { // Command键
              _this.$store.commit('designer/setKeepCtrl', true)
              if(_this.currentSelectLayoutItemId) {
                let tmpIds = _this.currentSelectLayoutItemIds.concat();
                tmpIds.pushNoRepeat(_this.currentSelectLayoutItemId);
                _this.$store.commit('designer/setCurrentSelectLayoutItemIds', tmpIds)
              }
              if(_this.currentSelectGroupItemId) {
                let tmpIds = _this.currentSelectGroupItemIds.concat();
                tmpIds.pushNoRepeat(_this.currentSelectGroupItemId);
                _this.$store.commit('designer/setCurrentSelectGroupItemIds', tmpIds)
              }
            }
          }else if(_this.$PnUtil.isWindows()) {
            if(ctrlKey) { // Ctrl键
              _this.$store.commit('designer/setKeepCtrl', true)
              if(_this.currentSelectLayoutItemId) {
                let tmpIds = _this.currentSelectLayoutItemIds.concat();
                tmpIds.pushNoRepeat(_this.currentSelectLayoutItemId);
                _this.$store.commit('designer/setCurrentSelectLayoutItemIds', tmpIds)
              }
              if(_this.currentSelectGroupItemId) {
                let tmpIds = _this.currentSelectGroupItemIds.concat();
                tmpIds.pushNoRepeat(_this.currentSelectGroupItemId);
                _this.$store.commit('designer/setCurrentSelectGroupItemIds', tmpIds)
              }
            }
          }

          if (e.keyCode == 37) { // 方向左键
            // 判断如果当前移动的是组，那么就不需要再执行moveLayoutItem
            if (_this.currentSelectGroupItemId || _this.currentSelectGroupItemIds.length > 0) {
              _this.currentSelectGroupItemLocation = _this.$DesignerCommonUtil.directionKeyMoveGroupItem(
                  'left', _this.currentSelectGroupItemId, _this.currentSelectGroupItemIds, _this.layout, null)
            }else {
              _this.$DesignerCommonUtil.directionKeyMoveLayoutItem(
                  'left', _this.currentSelectLayoutItemId, _this.currentSelectLayoutItemIds, _this.layout, _this.layoutGroup);
            }
            e.preventDefault()
          }
          else if(e.keyCode == 38) { // 方向上键
            if (_this.currentSelectGroupItemId || _this.currentSelectGroupItemIds.length > 0) {
              _this.currentSelectGroupItemLocation = _this.$DesignerCommonUtil.directionKeyMoveGroupItem(
                  'top', _this.currentSelectGroupItemId, _this.currentSelectGroupItemIds, _this.layout, null)
            }else {
              _this.$DesignerCommonUtil.directionKeyMoveLayoutItem(
                  'top', _this.currentSelectLayoutItemId, _this.currentSelectLayoutItemIds, _this.layout, _this.layoutGroup);
            }
            e.preventDefault()
          }
          else if(e.keyCode == 39) { // 方向右键
            if (_this.currentSelectGroupItemId || _this.currentSelectGroupItemIds.length > 0) {
              _this.currentSelectGroupItemLocation = _this.$DesignerCommonUtil.directionKeyMoveGroupItem(
                  'right', _this.currentSelectGroupItemId, _this.currentSelectGroupItemIds, _this.layout, null)
            }else {
              _this.$DesignerCommonUtil.directionKeyMoveLayoutItem(
                  'right', _this.currentSelectLayoutItemId, _this.currentSelectLayoutItemIds, _this.layout, _this.layoutGroup);
            }
            e.preventDefault()
          }
          else if(e.keyCode == 40) { // 方向下键
            if (_this.currentSelectGroupItemId || _this.currentSelectGroupItemIds.length > 0) {
              _this.currentSelectGroupItemLocation = _this.$DesignerCommonUtil.directionKeyMoveGroupItem(
                  'bottom', _this.currentSelectGroupItemId, _this.currentSelectGroupItemIds, _this.layout, null)
            }else {
              _this.$DesignerCommonUtil.directionKeyMoveLayoutItem(
                  'bottom', _this.currentSelectLayoutItemId, _this.currentSelectLayoutItemIds, _this.layout, _this.layoutGroup);
            }
            e.preventDefault()
          }
        });
        $(document).bind("keyup", function(e) {
          _this.keydownFlag = false;
          if(_this.$PnUtil.isMac()) {
            if(e.keyCode == 91) { // Command键
              _this.$store.commit('designer/setKeepCtrl', false)
            }
            if (e.keyCode == 93) {
              _this.$store.commit('designer/setKeepCtrl', false)
            }
          }else if(_this.$PnUtil.isWindows()) {
            if(e.keyCode == 17) { // Ctrl键
              _this.$store.commit('designer/setKeepCtrl', false)
            }
          }
        });
      },

      structureTreeTableClickHandler () {
        this.$store.commit('designer/clearAllSelected');
        this.registerKeyDownAndUp();
        this.locationTargetCanvas();
        return
      },

      locationTargetCanvas () {
        this.$store.commit('designer/setCanvasEnabled', true);
      },

      lockAndUnloadAll (enabled) {
        this.$store.commit('designer/setAllLayoutItemDraggableEnabled', {enabled: enabled});
        this.$store.commit('designer/setAllGroupItemDraggableEnabled', {enabled: enabled});
        if (enabled) {
          this.$Message.success('已解锁所有布局块与组')
        }else {
          this.$Message.success('已锁定所有布局块与组')
        }
      },

      showAndHideAll (display) {
        this.$store.commit('designer/setAllLayoutItemDisplay', {display: display});
        this.$store.commit('designer/setAllGroupItemDisplay', {display: display});
        if (display == 'block') {
          this.$Message.success('已显示所有布局块与组')
        }else if (display == 'none') {
          this.$Message.success('已隐藏所有布局块与组')
        }
      },

      toolBtnHandler(type) {
        let layoutItemIds = _.compact(_.union([this.currentSelectLayoutItemId], this.currentSelectLayoutItemIds.concat()));
        let groupItemIds = _.compact(_.union([this.currentSelectGroupItemId], this.currentSelectGroupItemIds.concat()));

        if (type == 'closeAllAlongShow') {
          if (this.alongShowTargetIdList.length > 0) {
            this.$DesignerCommonUtil.toggleAlongShowLayout('', [], 'cancelAll')
            return
          }
        }

        if (layoutItemIds.length > 0) {
          switch (type) {
            case 'createGroup':
              this.$DesignerCommonUtil.layoutItemCreateGroup(this.layoutGroup, layoutItemIds)
              break;
            case 'reverseLockItems':
              this.$DesignerCommonUtil.layoutItemReverseLock(layoutItemIds);
              break;
            case 'copyItems':
              this.$DesignerCommonUtil.layoutItemCopy(layoutItemIds);
              break;
            case 'delItems':
              this.$DesignerCommonUtil.layoutItemDelete(layoutItemIds);
              break;
          }
        }
        if (groupItemIds.length > 0) {
          switch (type) {
            case 'reverseLockItems':
              this.$DesignerCommonUtil.groupItemReverseLock(groupItemIds)
              break;
            case 'copyItems':
              this.$DesignerCommonUtil.groupItemCopy(groupItemIds)
              break;
            case 'delItems':
              this.$DesignerCommonUtil.groupItemDelete(groupItemIds);
              break;
          }
        }
      },

      toolBtnDisabled (type) {
        if (type == 'createGroup') {
          if (this.currentSelectLayoutItemId || this.currentSelectLayoutItemIds.length > 0)
            return false
        }
        if (this.currentSelectLayoutItemId || this.currentSelectLayoutItemIds.length > 0)
          return false
        if (this.currentSelectGroupItemId || this.currentSelectGroupItemIds.length > 0)
          return false
        return true
      }

    },
    computed: {
      ...mapFields({
        pageMetadata: 'pageMetadata',
        layout: 'pageMetadata.layout',
        layoutGroup: 'pageMetadata.layout.layoutGroup',
        currentSelectLayoutItemId: 'currentSelectLayoutItemId',
        currentSelectLayoutItemIds: 'currentSelectLayoutItemIds',
        currentSelectGroupItemId: 'currentSelectGroupItemId',
        currentSelectGroupItemIds: 'currentSelectGroupItemIds',
        canvasEnabled: 'canvasEnabled',
        alongShowTargetIdList: 'alongShowTargetIdList',
        isAlongCompEditModel: 'isAlongCompEditModel'
      }),
      structureTreeData () {

        let treeData = [];

        let storeLayoutGroup = this.$PnUtil.deepClone(this.pageMetadata.layout.layoutGroup);
        let allGroupItemIds = []; // 存储所有组内关联的布局块ID

        if (storeLayoutGroup && storeLayoutGroup.length > 0) {
          storeLayoutGroup.forEach(groupItem => {
            let treeItem = {
              type: 'groupItem',
              groupItemId: groupItem.id,
              groupItemName: groupItem.name,
              draggable: groupItem.groupItemConfigData.draggable,
              display: groupItem.groupItemConfigData.display,
              layoutItems: [

              ]
            };
            groupItem.layoutItemIds.forEach(layoutItemId => {
              allGroupItemIds.pushNoRepeat(layoutItemId);
            });

            if (this.currentSelectGroupItemIds.length > 0) {
              this.currentSelectGroupItemIds.indexOf(groupItem.id) > -1 ? treeItem._highlight = true : treeItem._highlight = false
            }else {
              this.currentSelectGroupItemId == groupItem.id ? treeItem._highlight = true : treeItem._highlight = false
            }

            treeData.push(treeItem)
          });
        }


        let storeLayoutItems = this.$PnUtil.deepClone(this.pageMetadata.layout.layoutItems);
        storeLayoutItems.sort(function (a, b) {
          return b.layoutItemConfigData.zIndex > a.layoutItemConfigData.zIndex ? 1 : -1
        });
        storeLayoutItems.forEach((item)=>{
          if (allGroupItemIds.indexOf(item.id) == -1) {
            let layoutItem = {
              type: 'layoutItem',
              layoutItemId: item.id,
              layoutItemName: item.name,
              layoutItemAliasName: item.aliasName,
              layoutItemDisplay: item.layoutItemConfigData.display,
              layoutItemDraggable: item.layoutItemConfigData.draggableEnabled,
              layoutItemIsStatic: item.layoutItemConfigData.isStatic,
              componentId: item.component.id,
              componentName: item.component.name,
              zIndex: item.layoutItemConfigData.zIndex
            };

            if (this.currentSelectLayoutItemIds.length > 0) {
              this.currentSelectLayoutItemIds.indexOf(item.id) > -1 ? layoutItem._highlight = true : layoutItem._highlight = false
            }else {
              this.currentSelectLayoutItemId == item.id ? layoutItem._highlight = true : layoutItem._highlight = false
            }

            treeData.push(layoutItem)
          }

        });


        return treeData;
      }
    }
  }
</script>

<style lang="less" scoped>

  .structure-tree-table {
    width: 100%;
    height: 100%;
    overflow: hidden;
    background-color: #424242;
    .toolbar {
      /*width: 100%;
      height: 33px;
      line-height: 31px;
      background-color: #616161;
      border-bottom: 1px solid #424242;
      padding: 0px 5px;
      position: sticky;
      top: 0px;
      z-index: 3;
      margin-top: -2px;*/
      height: 33px;
      line-height: 33px;
      padding: 0px 5px;
      background-color: #616161;
      border-bottom: 1px solid #424242;
      text-align: center;
    }

    .structure-tree-body {
      width: 100%;
      height: calc(100% - 33px);
      /*padding: 10px;*/
      overflow-x: hidden;
      overflow-y: auto;
      padding-bottom: 33px;
    }

    .structure-tree-footer {
      position: absolute;
      bottom: 0px;
      width: 100%;
      height: 33px;
      background-color: #2E2E2E;
      text-align: center;
      line-height: 33px;
    }

    .tool-btn {
      padding: 5px;
      cursor: pointer;
      &:hover {
        background-color: #2196f3;
        border-radius: 3px;
      }
      &.disabled {
        opacity: 0.55;
        cursor: not-allowed;
        &:hover {
          background-color: inherit;
        }
      }
    }

  }

  .canvas-item {
    width: 100%;
    height: auto;
    background-color: rgb(14, 43, 67);
    border: 1px solid rgb(14, 43, 67);
    position: sticky;
    top: 0px;
    z-index: 999;
    &:hover {
      border: 1px solid #4AFFFF;
    }
    &.active {
      border: 1px solid #4AFFFF;
    }
    .content {
      color: #fff;
      position: relative;
      padding: 6px;
      .text {
        display: inline-block;
        font-size: 14px;
      }
    }
  }

  .none-message {
    font-size: 1.5em;
    font-weight: bold;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    opacity:0.5;
    color: #fff;
  }

</style>
